﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Diagnostics;

namespace Sparkle.UI
{
    /// <summary>
    /// RegisterdControl used for register default controls with UIDefaults
    /// </summary>
    public class RegisterdControl : IRegisterdControl
    {
        public delegate void CreateControlDelegate(Control control);

        public CreateControlDelegate OnCreateingControl = null;

        public delegate void DataBindingDelegate(Control control, object value);

        public DataBindingDelegate OnDataBinding = null;

        public Type ControlType { get; set; }

        private string _namePreFix = "Cnt";
        /// <summary>
        /// Gets or sets the control name prefix.
        /// </summary>
        /// <value>The name pre fix.</value>
        public string NamePreFix 
        {
            get { return _namePreFix; }
            set { _namePreFix =value; }
        }

        public DependencyProperty BindingProperty { get; set; }

        #region DefaultWidth

        int _defaultWidth = 100;

        /// <summary>
        /// Gets or sets the default width.
        /// </summary>
        /// <value>The default width.</value>
        public int DefaultWidth
        {
            get { return _defaultWidth; }
            set { _defaultWidth = value; }
        }

        #endregion

        #region DefaultHeight
        private int _defaultHeight = 0;
        /// <summary>
        /// Gets or sets the default height.
        /// </summary>
        /// <value>The default height.</value>
        public int DefaultHeight
        {
            get { return _defaultHeight; }
            set { _defaultHeight = value; }
        }

        #endregion DefaultHeight

        #region Public Methods

        /// <summary>
        /// Cteates the control.
        /// </summary>
        /// <param name="metadata">The metadata.</param>
        /// <returns></returns>
        public virtual Control CteateControl(Metadata metadata)
        {
            Control control = null;
            try
            {
                control = (Control)Activator.CreateInstance(this.ControlType);

                control.Name = string.Format("{0}.{1}", NamePreFix, metadata.Name);

                if (OnCreateingControl != null)
                {
                    OnCreateingControl(control);
                }
            }
            catch (Exception ex)
            {
                Debug.WriteLine(string.Format("Creating {0} Control Error {1}.", metadata.FullName, ex.Message));
            }

            return control; 
        }

        /// <summary>
        /// Sets the binding.
        /// </summary>
        /// <param name="control">The control.</param>
        /// <param name="metadata">The metadata.</param>
        /// <param name="entity">The entity.</param>
        public virtual void SetBinding(Control control, Metadata metadata, object entity)
        {

            MetaBinding bind = new MetaBinding(metadata.Name);

#if  !SILVERLIGHT

            bind.ValidationRules.Add(new ExceptionValidationRule());
#endif

            bind.Converter = metadata;

            if (metadata.ReadOnly)
            {
                bind.Mode = BindingMode.OneWay;
            }
            else
            {
                bind.Mode = BindingMode.TwoWay;
            }

            bind.NotifyOnValidationError = metadata.NotifyOnValidationError;
            bind.ValidatesOnExceptions = metadata.NotifyOnValidationError;
            bind.UpdateSourceTrigger =  UpdateSourceTrigger.Default;

            bind.Source = entity;

            //DependencyProperty.RegisterAttached(
            //http://stackoverflow.com/questions/834929/silverlight-how-to-receive-notification-of-a-change-in-an-inherited-dependencypr
            
            control.SetBinding(this.BindingProperty, bind);

            if (OnDataBinding != null)
            {
                OnDataBinding(control, metadata.GetValue(entity));
            }   
        }
        #endregion
    }

}
